<?php

namespace App\Http\Controllers\V1\API;

use App\Http\Controllers\V1\API\BaseController;
use App\Models\V1\AdminUser;
use App\Models\V1\WeChatLogin;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Auth;
use Illuminate\Support\Facades\Redis;
use Log;
use Validator;

include_once 'wxBizDataCrypt.php';

class WeChatController extends BaseController
{
    protected $app_id = 'wx6397396df988f501';
    protected $app_secret = 'f767a74b8fa834acbdf55971e858cb81';
    protected $we_uri = 'https://api.weixin.qq.com/sns/jscode2session';


    /***
     * 微信登录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function wechatLogin(Request $request)
    {
        $result = array(
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
        );
        $code = $request['code'];
        if (empty($code) || !isset($code)) {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = '参数不正确';
            return $this->sendResponse($result, $result['errorCode']);
        }
        $dir = dirname(__FILE__);

//    $client = new \GuzzleHttp\Client(['verify' => '/etc/letsencrypt/live/wechat.yejinsoft.com/fullchain.pem']);
        $client = new \GuzzleHttp\Client(['verify' => $dir . '/DigiCert_Global_Root_CA.pem']);
//        $client = new \GuzzleHttp\Client(['verify' => $dir . '/cacert.pem']);
        $uri = $this->we_uri.'?appid=' . $this->app_id . '&secret=' . $this->app_secret . '&js_code=' . $code . '&grant_type=authorization_code';
        $response = $client->request('GET', $uri);
        $response = json_decode((string)$response->getBody(), true);
        if (key_exists('errcode', $response)) {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = $response['errmsg'].$response['errcode'];
        } else {
            //创建3rdSession
            $result_session = $this->creat3rdSession();

            Log::info('wechatLogin::thirdSession ===='.$result_session);

            $open_id = $response['openid'];
            Log::info('wechatLogin::$open_id ===='.$open_id);
            $session_key = $response['session_key'];

            Log::info('wechatLogin::session_key ===='.$session_key);

            //以3rdSession为key,openid+session_key为value保存到数据库中
            $this->save3rdSession($open_id,$session_key,$result_session);
            $result['errorCode'] = Response::HTTP_OK;
            $result['errorMsg'] = '成功';
            $result['data'] = [
                'thirdSession' => $result_session
            ];
        }
        return $this->sendResponse($result, $result['errorCode']);
    }


    /****
     * 退出登录
     * @param Request $request
     */
    public function wechatLogout(Request $request) {
        $result = array(
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
        );
        $code = $request->get('userID');
        if (empty($code) || !isset($code)) {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = '参数不正确';
            return $this->sendResponse($result, $result['errorCode']);
        }
        $rspObj = $this->unRelateUser($code);
        if ($rspObj) {
            $result['errorCode'] = Response::HTTP_OK;
            $result['errorMsg'] = '成功';
        }else {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = '失败';
        }
        return $this->sendResponse($result, $result['errorCode']);
    }



    /***
     * 获取unionid
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getUserInfo(Request $request)
    {
        $result = array(
            'errorCode' => Response::HTTP_NOT_FOUND,
            'errorMsg' => Response::$statusTexts[Response::HTTP_NOT_FOUND],
        );
        $encryptedData = $request->get('encryptedData');
        Log::info('$encryptedData = '.$encryptedData);
        $iv = $request->get('iv');
        Log::info('$iv = '.$iv);
        $third_session = $request->get('thirdSession');
        Log::info('$third_session = '.$third_session);

        $error = $this->validateUserInfo($request, $result);
        if (!empty($error) || isset($error)) {
            $result = $error;
            return $this->sendResponse($result, $result['errorCode']);
        }
//        根据$third_session取出session_key
        $session_key = $this->getSessionKey($third_session,$result);
//        返回数组说明$third_session 不存在，可能已过期
        if (is_array($session_key)) {
            $result = $session_key;
            return $this->sendResponse($result, $result['errorCode']);
        }
        Log::info('userinfo::session_key  ===== '.$session_key);
        $wxBizDataCrypt = new \WXBizDataCrypt($this->app_id, $session_key);
        $error_code = $wxBizDataCrypt->decryptData($encryptedData, $iv, $data);
        Log::info('userinfo::$data  ===== ',['data'=>$data]);
        if ($error_code == 0) {
            $data = json_decode($data,true);
//            $union_id = $data['unionId'];
            $union_id = $data['openId'];
            Log::info('userinfo::$union_id  ===== '.$union_id);
            $result = $this->relateUser($union_id,$result);
        }else {
            $result['errorCode'] = Response::HTTP_OK;
            $result['errorMsg'] =$error_code;
        }
        return $this->sendResponse($result, $result['errorCode']);
    }


    /**
     * 生成3rd_session
     * @return
     */
    private function creat3rdSession(){
        $pr_bits = '';
        $fp = @fopen('/dev/urandom','rt');
        if ($fp !== false) {
            $pr_bits = @fread($fp,126);
            @fclose($fp);
        }
        $result = base64_encode($pr_bits);
        $result = strtr($result, '+/', '-_');
        $result = str_replace('=', ' ', $result);
        return $result;
    }
    /***
     * 保存$session_key到数据库
     * @param $open_id
     * @param $session_key
     * @param $third_session
     */
    private function save3rdSession($open_id, $session_key,$third_session) {
        Redis::set($third_session, $open_id.' '.$session_key);
        Redis::expire($third_session, 7200);
    }

    /***
     * 根据$third_session从数据库取出sessionKey
     * @param $third_session
     */
    private function getSessionKey($third_session, $result) {
        if (Redis::exists($third_session)) {
            $session_key = Redis::get($third_session);
            $sessionArr = explode(' ',$session_key);
            if (count($sessionArr)==2){
                return $sessionArr[1];
            }else {
                $result['errorCode'] = Response::HTTP_BAD_REQUEST;
                $result['errorMsg'] = 'thirdSession不正确或已过期';
                return $result;
            }
        }else {
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = 'thirdSession不正确或已过期';
            return $result;
        }
    }

    /***
     * 检测用户有没有关联
     * @param $union_id
     * @param $result
     * @return mixed
     */
    private function relateUser($union_id, $result) {
        $weChatUser = WeChatLogin::where('unionid',$union_id)->first();
        if (empty($weChatUser) || !isset($weChatUser)) {
            //未关联用户
            $data ['type'] = 1;
            $result['data'] = $data;
            $result['errorCode'] = Response::HTTP_OK;
            $result['errorMsg'] ='成功';
        }else {
            //已关联，获取token
            $user = AdminUser::where('code',$weChatUser->exam_code)->first();
            $token = $user->createToken($weChatUser->exam_code)->accessToken;
            $data ['type'] = 2;
            $data ['access_token'] = $token;
            $data ['userID'] = $weChatUser->exam_code;
            $result['data'] = $data;
            $result['errorCode'] = Response::HTTP_OK;
            $result['errorMsg'] ='成功';
        }
        return $result;
    }


    /***
     * 解除绑定
     * @param $code
     * @return mixed
     */
    private function unRelateUser($code) {
        $user = WeChatLogin::where('exam_code',$code)->first();
        if (empty($user)) {
            return true;
        }else {
            $rspObj = WeChatLogin::where('exam_code',$code)->delete();
            return $rspObj;
        }
    }

    /***
     * 验证参数
     * @param Request $request
     * @return mixed
     */
    public function validateUserInfo(Request $request, $result)
    {
        //校验规则
        $rules = array();
        $rules['encryptedData'] = 'required';
        $rules['iv'] = 'required';
        $rules['thirdSession'] = 'required';

        //错误提示信息
        $messages = array();
        $messages['encryptedData.required'] = 'encryptedData不能为空';
        $messages['iv.required'] = 'iv不能为空';
        $messages['thirdSession.required'] = 'thirdSession不能为空';
        $validator = Validator::make($request->all(),$rules,$messages);  //第一个参数是提交的数据，第二个是校对规则，第三个是错误信息
        $errors = $validator->errors()->all(); //这是捕获到的所有参数验证的错误信息
        if(!empty($errors)) {
            $first_errors = $errors[0];
            $result['errorCode'] = Response::HTTP_BAD_REQUEST;
            $result['errorMsg'] = $first_errors;
            return $result;
        }
    }

}